package com.firsteapps.mobile.android.puzzle.game;

import android.content.Context;
import android.graphics.Canvas;
import android.media.MediaPlayer;
import android.os.Vibrator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class DrawView extends View {

	private Puzzle puzzle;
	Tile mMovingTile = null;
	int mCurrX = 0;
	int mCurrY = 0;
	int mDeltaX;
	int mDeltaY;
	private int puzzleSize;
	private PuzzleCompletedCallback puzzleCompletedCallback;
	private MoveActionListener moveListener;
	private MediaPlayer mp;
	private boolean soundsEnabled;
	private boolean vibrationEnabled;

	public int getPuzzleSize() {
		return puzzleSize;
	}

	public void setPuzzleSize(int puzzleSize) {
		this.puzzleSize = puzzleSize;
	}

	public boolean isSoundsEnabled() {
		return soundsEnabled;
	}

	public void setSoundsEnabled(boolean soundsEnabled) {
		this.soundsEnabled = soundsEnabled;
	}

	public boolean isVibrationEnabled() {
		return vibrationEnabled;
	}

	public void setVibrationEnabled(boolean vibrationEnabled) {
		this.vibrationEnabled = vibrationEnabled;
	}

	public MediaPlayer getMp() {
		return mp;
	}

	public void setMp(MediaPlayer mp) {
		this.mp = mp;
	}

	public DrawView(Context context, AttributeSet attrs) {
		super(context, attrs);
		setFocusable(true);
//		soundsEnabled = Settings.isSoundEnabled(context);
//		vibrationEnabled = Settings.isVibrationEnabled(context);
//		Settings.setEffectsChanged(new EffectsChangedCallback() {
//
//			@Override
//			public void onChangedVibration(boolean enabled) {
//				vibrationEnabled = enabled;
//			}
//
//			@Override
//			public void onChangedSound(boolean enabled) {
//				soundsEnabled = enabled;
//			}
//		});
	}

	public void setMoveListener(MoveActionListener moveListener) {
		this.moveListener = moveListener;
	}

	public void setPuzzleCompleted(PuzzleCompletedCallback puzzleCompletedCallback) {
		this.puzzleCompletedCallback = puzzleCompletedCallback;

	}

	@Override
	protected void onDraw(Canvas canvas) {
		System.out.println("onDraw called");
		if (puzzle != null) {
			puzzle.Draw(canvas);
			Log.d("DrawView", "onDraw");
		}
	}

	@Override
	protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
		super.onLayout(changed, left, top, right, bottom);
		System.out.println("onLayout called");
		if (puzzle != null && !puzzle.isCreated()) {
			puzzle.create(puzzleSize, right - left, bottom - top);
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (isFocusable()) {
			int eventaction = event.getAction();

			int x = (int) event.getX();
			int y = (int) event.getY();

			if (puzzle != null) {
				switch (eventaction) {

				case MotionEvent.ACTION_DOWN:
					mMovingTile = getTile(x, y);
					mCurrX = x;
					mCurrY = y;
					mDeltaX = mDeltaY = 0;
					break;

				// case MotionEvent.ACTION_MOVE: // touch drag with the ball
				// if (mMovingTile != null) {
				// mDeltaX = x - mCurrX;
				// mDeltaY = y - mCurrY;
				// getPuzzle().moveBy(mMovingTile, mDeltaX, mDeltaY);
				// mCurrX = x;
				// mCurrY = y;
				// invalidate();
				// }
				// break;

				case MotionEvent.ACTION_UP:
					if (mMovingTile != null && getPuzzle().isAdjacentTile(mMovingTile)) {
						int movesIncreased = getPuzzle().moveTile(mMovingTile);

						if (getPuzzle().isMoving()) {
							if (soundsEnabled)
								mp.start();
							if (vibrationEnabled) {
								Vibrator v = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
								v.vibrate(100);
							}
							getPuzzle().resetMoving();
						}

						if (getPuzzle().isCompleted())
							puzzleCompletedCallback.onPuzzleCompleted();

						if (movesIncreased == 1)
							moveListener.onMovePerformed();
						else if (movesIncreased == 2)
							moveListener.onMoveRejected();

						mMovingTile = null;
						invalidate();
						System.out.println("DrawView Invalidate");
					}
					break;
				}
			}

			return true;
		}
		return false;
	}

	private Tile getTile(int x, int y) {

		return getPuzzle().getTile(x, y);
	}

	public void setPuzzle(Puzzle puzzle) {
		this.puzzle = puzzle;
		requestLayout();
	}

	public Puzzle getPuzzle() {
		return puzzle;
	}

}